package com.ucode.springboot.starter.canal.config;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 * canal 配置
 * @author: liliang
 * @date: 2020年2月27日 上午11:27:12
 */
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConfigurationProperties(prefix = "canal.client")
public class CanalConfig {

    /**
     * 配置信息
     */
    private Map<String, Instance> instances = new LinkedHashMap<>();
    
    
    public Map<String, Instance> getInstances() {
        return instances;
    }

    public void setInstances(Map<String, Instance> instances) {
        this.instances = instances;
    }

    /**
     * canal 配置类
     * @author: liliang
     * @date: 2020年2月27日 上午11:29:32
     */
    public static class Instance {
        /**
         * 是否是集群模式
         */
        private boolean clusterEnabled;
        
        /**
         * zookeeper 地址
         */
        private Set<String> zookeeperAddress = new LinkedHashSet<>();
        
        /**
         * canal 服务器地址，默认是本地的环回地址
         */
        private String host = "127.1.1.1";
        
        /**
         * canal 服务设置的端口，默认 11111
         */
        private int port = 11111;

        /**
         * 集群 设置的用户名
         */
        private String userName = "";

        /**
         * 集群 设置的密码
         */
        private String password = "";

        /**
         * 批量从 canal 服务器获取数据的最多数目
         */
        private int batchSize = 1000;

        /**
         * Filter模块->【【【【【这里谨慎设置】】】】】
         * 过滤规则的配置既可以在canal服务端进行，也可以在客户端进行
         * 注意：1.在过滤的时候，会先根据白名单进行过滤，再根据黑名单过滤。意味着，如果一张表在白名单和黑名单中都出现了，那么这张表最终不会被订阅到，因为白名单通过后，黑名单又将这张表给过滤掉了;
         * 2.过滤规则使用的是perl正则表达式，而不是jdk自带的正则表达式
         * 一、服务端配置:
         * canal.instance.filter.regex=.*\\..*
         * ->mysql 数据解析表的白名单,也就是我们希望订阅哪些库，哪些表，默认值为.\..，也就是订阅所有库，所有表
         * canal.instance.filter.black.regex=
         * ->mysql 数据解析表的黑名单，表达式规则见白名单的规
         * 二、客户端配置
         * canal也支持客户端配置过滤规则。举例来说，假设一个库有10张表，一个client希望订阅其中5张表，另一个client希望订阅另5张表。此时，服务端可以订阅10张表，当client来消费的时候，根据client的过滤规则只返回给对应的binlog event
         * 客户端指定过滤规则通过client模块中的CanalConnector的subscribe方法来进行，subscribe有两种重载形式，如下：
         * 1.不指定filter，以服务端的filter为准
         * 2.指定了filter，目前会直接替换canal server服务端配置的filter信息，以本次提交的为准
         * 设计者初衷：
         * 通过不同client指定不同的过滤规则，可以达到服务端一份数据供多个client进行订阅消费的效果， 
         * 然而，想法是好的，现实确是残酷的，由于目前一个canal instance只允许一个client订阅，因此目前还达不到这种效果。读者明白这种设计的初衷即可
         */
        private String filter;

        /**
         * 当错误发生时，重试次数
         */
        private int retryCount = 5;

        /**
         * 信息捕获心跳时间
         */
        private long acquireInterval = 1000;

        public boolean isClusterEnabled() {
            return clusterEnabled;
        }

        public void setClusterEnabled(boolean clusterEnabled) {
            this.clusterEnabled = clusterEnabled;
        }

        public Set<String> getZookeeperAddress() {
            return zookeeperAddress;
        }

        public void setZookeeperAddress(Set<String> zookeeperAddress) {
            this.zookeeperAddress = zookeeperAddress;
        }

        public String getHost() {
            return host;
        }

        public void setHost(String host) {
            this.host = host;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public int getBatchSize() {
            return batchSize;
        }

        public void setBatchSize(int batchSize) {
            this.batchSize = batchSize;
        }

        public String getFilter() {
            return filter;
        }

        public void setFilter(String filter) {
            this.filter = filter;
        }

        public int getRetryCount() {
            return retryCount;
        }

        public void setRetryCount(int retryCount) {
            this.retryCount = retryCount;
        }

        public long getAcquireInterval() {
            return acquireInterval;
        }

        public void setAcquireInterval(long acquireInterval) {
            this.acquireInterval = acquireInterval;
        }
        
    }
}
